package de.hfu.helper;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Locale;
import java.util.StringTokenizer;

import de.hfu.model.DayPlan;
import de.hfu.model.Dish;

public class DataParser {

//	public static final String FURTWANGEN_URL = "http://www.studentenwerk.uni-freiburg.de/rss/641/";
	public static final String FURTWANGEN_URL = "http://www.swfr.de/essen-trinken/speiseplaene/speiseplan-rss/?no_cache=1&Tag=&Ort_ID=641";
//	public static final String SCHWENNINGEN_URL = "http://www.studentenwerk.uni-freiburg.de/rss/671/";
		public static final String SCHWENNINGEN_URL = "http://www.swfr.de/de/essen-trinken/speiseplaene/speiseplan-rss/?no_cache=1&Tag=&Ort_ID=671";
	public static final String GAE_SERVER = "http://mensa-plan-server.appspot.com/";
	public static final int CONNECTION_TIMEOUT = 1000 * 5;

	private static DataParser instance = new DataParser();

	private DataParser() {
	}

	public static DataParser getInstance() {
		return instance;
	}

	public DayPlan getMenuOfDate(String url, Date date)
			throws MalformedURLException, ParseException {
		SimpleXMLParser xmlParser = new SimpleXMLParser(new URL(url));
		xmlParser.nextTagContent("title");

		String tmp = xmlParser.nextTagContent("title");

		while (tmp.trim().length() > 0) {
			SimpleDateFormat s = new SimpleDateFormat("E, dd.MM.yyyy",
					Locale.GERMAN);
			Date tmpDate = s.parse(tmp);
			if (date.equals(tmpDate)) {
				DayPlan menu = new DayPlan();
				menu.setDishes(getDishesFromCData(xmlParser
						.nextTagContent("description")));
				menu.setDate(date);
				return menu;
			}
			// if (isEqual(date, tmpDate)) {
			// return getMenuOfCData(xmlParser.nextTagContent("description"));
			// }
			tmp = xmlParser.nextTagContent("title");
		}
		return null;
	}

	public DayPlan getMenuOfDate(Date date, String text)
			throws MalformedURLException, ParseException {
		SimpleXMLParser xmlParser = new SimpleXMLParser(text);
		xmlParser.nextTagContent("title");

		String tmp = xmlParser.nextTagContent("title");

		while (tmp.trim().length() > 0) {
			SimpleDateFormat s = new SimpleDateFormat("E, dd.MM.yyyy",
					Locale.GERMAN);
			Date tmpDate = s.parse(tmp);
			if (date.equals(tmpDate)) {
				DayPlan menu = new DayPlan();
				menu.setDishes(getDishesFromCData(xmlParser
						.nextTagContent("description")));
				menu.setDate(date);
				return menu;
			}
			// if (isEqual(date, tmpDate)) {
			// return getMenuOfCData(xmlParser.nextTagContent("description"));
			// }
			tmp = xmlParser.nextTagContent("title");
		}
		return null;
	}

	private ArrayList<DayPlan> getAllMenuFromRSSOnline(String url)
			throws MalformedURLException, ParseException {
		ArrayList<DayPlan> result = new ArrayList<DayPlan>();
		SimpleXMLParser xmlParser = new SimpleXMLParser(new URL(url));
		xmlParser.nextTagContent("title");

		String tmp = xmlParser.nextTagContent("title");

		while (tmp.trim().length() > 0) {
			SimpleDateFormat s = new SimpleDateFormat("E, dd.MM.yyyy",
					Locale.GERMAN);
			Date tmpDate = s.parse(tmp);

			DayPlan menu = new DayPlan();

			menu.setDishes(getDishesFromCData(xmlParser
					.nextTagContent("description")));
			menu.setDate(tmpDate);

			result.add(menu);

			tmp = xmlParser.nextTagContent("title");
		}

		return result;

	}

	@SuppressWarnings("unused")
	private ArrayList<DayPlan> getAllMenusFromRSS(String text)
			throws ParseException {
		ArrayList<DayPlan> result = new ArrayList<DayPlan>();
		SimpleXMLParser xmlParser = new SimpleXMLParser(text);
		xmlParser.nextTagContent("title");

		String tmp = xmlParser.nextTagContent("title");

		while (tmp.trim().length() > 0) {
			SimpleDateFormat s = new SimpleDateFormat("E, dd.MM.yyyy",
					Locale.GERMAN);
			Date tmpDate = s.parse(tmp);

			DayPlan menu = new DayPlan();

			menu.setDishes(getDishesFromCData(xmlParser
					.nextTagContent("description")));
			menu.setDate(tmpDate);

			result.add(menu);

			tmp = xmlParser.nextTagContent("title");
		}

		return result;
	}

	private ArrayList<Dish> getDishesFromCData(String CData) {

		ArrayList<Dish> result = new ArrayList<Dish>();

		CData = CData.replace("]]><![CDATA[", "");

		int tmp1 = CData.indexOf("<u>") + 3;
		int tmp2 = CData.indexOf("</u>", tmp1);
		boolean ck = true;
		while (ck) {
			String tmpTitle = CData.substring(tmp1, tmp2).trim();
			int tmp3 = CData.indexOf("<u>", tmp2 + 4);
			if (tmp3 == -1) {
				tmp3 = CData.indexOf("]]>", tmp2) + 1;
				ck = false;
			}
			String dishStr = CData.substring(tmp2 + 4, tmp3 - 1).trim();
			if (tmpTitle.length() > 0 || dishStr.length() > 0) {
				String dishDesc = getDishDesc(dishStr);
				if (dishDesc.trim().length() > 0) {
					Dish dish = new Dish(tmpTitle);
					dish.setDescription(dishDesc.trim());
					result.add(dish);
				}
			}
			tmp1 = CData.indexOf("<u>", tmp2) + 3;
			tmp2 = CData.indexOf("</u>", tmp1);
		}

		return result;
	}

	private String getDishDesc(String dishStr) {

		int tmp1 = dishStr.indexOf("<br>") + 4;
		int tmp2 = dishStr.indexOf("<br>", tmp1);
		StringBuilder dishNameBuilder;
		String tmp;
		String desc = "";
		while (tmp2 > -1) {
			dishNameBuilder = new StringBuilder(dishStr.substring(tmp1, tmp2)
					.trim());
			while (dishNameBuilder.indexOf("<") > -1) {
				dishNameBuilder.delete(dishNameBuilder.indexOf("<"),
						dishNameBuilder.indexOf(">") + 1);
			}
			tmp = dishNameBuilder.toString().trim();
			if (tmp.length() > 0) {
				if (desc.length() > 0)
					desc += "\n" + tmp;
				else
					desc += tmp;
			}
			tmp1 = tmp2 + 4;
			tmp2 = dishStr.indexOf("<br>", tmp1);
		}

		return desc;
	}

	public ArrayList<DayPlan> getDataFromInternet(String campusName)
			throws MalformedURLException, ParseException {
		if (campusName.equalsIgnoreCase("Schwenningen"))
			return getAllMenuFromRSSOnline(SCHWENNINGEN_URL);
		return getAllMenuFromRSSOnline(FURTWANGEN_URL);
	}

	public String getCommentFromGAE(String name, Date date) {

		try {
			String urlStr = GAE_SERVER + "get_comment?dish_title="
					+ URLEncoder.encode(name, "UTF-8") + "&dish_date="
					+ (new SimpleDateFormat("yyyy-MM-dd")).format(date);

			URL url = new URL(urlStr);
			URLConnection urlConnection = url.openConnection();
			urlConnection.setConnectTimeout(CONNECTION_TIMEOUT);
			urlConnection.connect();
			InputStream input = url.openStream();
			Reader reader = new InputStreamReader(input, "UTF-8");
			BufferedReader bufferedReader = new BufferedReader(reader);
			String text = bufferedReader.readLine();
			if (text != null) {
				String result = "";

				for (String x : text.split("&&")) {
					String[] tmp = x.split("\\|\\|");
					result += tmp[1].substring(0, tmp[1].indexOf('.')) + "\n\t"
							+ tmp[0] + "\n";
				}
				return result;
			}
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	public boolean postCommentToGAE(String name, Date date, String content) {

		try {
			String urlStr = GAE_SERVER + "comment?dish_title="
					+ URLEncoder.encode(name, "UTF-8") + "&dish_date="
					+ (new SimpleDateFormat("yyyy-MM-dd")).format(date)
					+ "&content=" + URLEncoder.encode(content, "UTF-8");

			URL url = new URL(urlStr);
			URLConnection urlConnection = url.openConnection();
			urlConnection.setConnectTimeout(CONNECTION_TIMEOUT);
			urlConnection.connect();

			url.openStream().close();

			return true;
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return false;
	}

	public float getRatingFromGAE(String name, Date date) {

		try {
			String urlStr = GAE_SERVER + "get_rating?dish_title="
					+ URLEncoder.encode(name, "UTF-8") + "&dish_date="
					+ (new SimpleDateFormat("yyyy-MM-dd")).format(date);

			URL url = new URL(urlStr);
			URLConnection urlConnection = url.openConnection();
			urlConnection.setConnectTimeout(CONNECTION_TIMEOUT);
			urlConnection.connect();
			InputStream input = url.openStream();
			Reader reader = new InputStreamReader(input, "UTF-8");
			BufferedReader bufferedReader = new BufferedReader(reader);
			String text = bufferedReader.readLine();

			float result = Float.parseFloat(text);

			return result / 20;
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NumberFormatException e) {
		}
		return -1;
	}

	public boolean postRatingToGAE(String name, Date date, float rating) {

		try {
			String urlStr = GAE_SERVER + "rating?dish_title="
					+ URLEncoder.encode(name, "UTF-8") + "&dish_date="
					+ (new SimpleDateFormat("yyyy-MM-dd")).format(date)
					+ "&rate=" + (int) (rating * 20);

			URL url = new URL(urlStr);
			URLConnection urlConnection = url.openConnection();
			urlConnection.setConnectTimeout(CONNECTION_TIMEOUT);
			urlConnection.connect();

			url.openStream().close();

			return true;
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return false;
	}	
}
